package com.peoit.honeycomb.application.impl;

import com.google.common.collect.Sets;
import com.peoit.honeycomb.application.SecurityApplication;
import com.peoit.honeycomb.application.utils.ManageUtils;
import com.peoit.honeycomb.domain.BaseEntity;
import com.peoit.honeycomb.domain.User;
import com.peoit.honeycomb.domain.repository.HibernateEntityRepository;
import com.peoit.honeycomb.domain.security.Permission;
import com.peoit.honeycomb.domain.security.Person;
import com.peoit.honeycomb.domain.security.Role;
import com.peoit.honeycomb.dto.InformationDto;
import com.peoit.honeycomb.dto.UserQueryDto;
import com.peoit.honeycomb.dto.security.*;
import com.peoit.honeycomb.util.CommonUtil;
import org.springframework.stereotype.Service;
import org.apache.commons.lang3.StringUtils;

import javax.transaction.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.UUID;

/**
 * Created by zhouqiu on 2015/10/15.
 */
@Service
public class SecurityApplicationImpl  extends HibernateEntityRepository implements SecurityApplication {

    private PersonDto person = new PersonDto();
    private RoleDto role= new RoleDto();
    private PermissionDto permission = new PermissionDto();

    @Override
    public List<PermissionDto> findpermissionPageBy(PermissionPageDto dto) {

        int pageSize = dto.getPageSize();
        int offset = dto.getOffset();

        List<Object> parameters = new ArrayList<>();

        StringBuffer where = new StringBuffer("") ;

        if (!StringUtils.isEmpty(dto.getName())){
            if(where.length()>0){
                where.append(" AND ");
            }
            where.append(" name like ? ");
            parameters.add("%"+dto.getName()+"%");
        }
        if (!StringUtils.isEmpty(dto.getDescription())){
            if(where.length()>0){
                where.append(" AND ");
            }
            where.append(" description like ? ");
            parameters.add("%"+dto.getDescription()+"%");
        }

        if(where.length()>0){
            where.append(" AND ");
        }
        where.append(" 1=1 order by createTime desc");

        List<Permission> permissions = queryByWherePage(Permission.class, where.toString(), CommonUtil.listToArray(parameters), offset, pageSize);
        List<PermissionDto> permissionDtos = permission.toPageDto(permissions);
        return  permissionDtos;
    }


    @Override
    @Transactional
    public boolean addPermission(PermissionDto permissionDto) {
        Permission parentPermission = null;
        if (StringUtils.isNotBlank(permissionDto.getParentPermissionId())) {
            parentPermission = (Permission) super.find(Permission.class, permissionDto.getParentPermissionId());
        } else {
            parentPermission = (Permission) super.find(Permission.class, "1");
        }

        //设置权限所处等级
        String level = String.valueOf(Integer.valueOf(parentPermission.getLevel()) + 1);
        permissionDto.setLevel(level);
        //保存更新
        if(StringUtils.isNotBlank(permissionDto.getId())) {
            update(permission.toEntity(permissionDto, parentPermission));
        }else {
            Permission permission = this.permission.toEntity(permissionDto, parentPermission);
            permission.setId(  ManageUtils.getNumber());
            create(permission);
        }
        return true;
    }


    @Override
    public List<RoleDto> findRolePageBy(RolePageDto dto) {
        int pageSize = dto.getPageSize();
        int offset = dto.getOffset();

        List<Object> parameters = new ArrayList<>();

        StringBuffer where = new StringBuffer("") ;

        if (!StringUtils.isEmpty(dto.getName())){
            if(where.length()>0){
                where.append(" AND ");
            }
            where.append(" name like ? ");
            parameters.add("%"+dto.getName()+"%");
        }
        if (!StringUtils.isEmpty(dto.getDescription())){
            if(where.length()>0){
                where.append(" AND ");
            }
            where.append("  description like ? ");
            parameters.add("%"+dto.getDescription()+"%");
        }
        if(where.length()>0){
            where.append(" AND ");
        }
        where.append(" 1=1 order by createTime desc");

        List<Role> roles = queryByWherePage(Role.class, where.toString(), CommonUtil.listToArray(parameters), offset, pageSize);
        List<RoleDto> roleDtos = role.toPageDto(roles);
        return  roleDtos;
    }

    @Override
    @Transactional
    public boolean roleCreateOrUpdate(RoleDto roleDto,String [] perId) {
        Set<Permission> sets = Sets.newHashSet();
        for (String ids : perId) {
            if(StringUtils.isNotBlank(ids)) {
                Permission permission1 = find(Permission.class,ids);
                sets.add(permission1);
            }
        }
        Role role2 = roleDto.toEntity(roleDto, sets);
        if(StringUtils.isNotBlank(roleDto.getId())){
            this.update(role2);
        }else {

            role2.setId(  ManageUtils.getNumber());
            this.create(role2);
        }
        return true;
    }



    @Override
    public List<PersonDto> findPersonPageBy(PersonPageDto dto) {

        int pageSize = dto.getPageSize();
        int offset = dto.getOffset();

        List<Object> parameters = new ArrayList<>();

        StringBuffer where = new StringBuffer("") ;

        if (!StringUtils.isEmpty(dto.getName())){
            if(where.length()>0){
                where.append(" AND ");
            }
            where.append(" name like ? ");
            parameters.add("%"+dto.getName()+"%");
        }
        if (!StringUtils.isEmpty(dto.getDescription())){
            if(where.length()>0){
                where.append(" AND ");
            }
            where.append(" description like ? ");
            parameters.add("%"+dto.getDescription()+"%");
        }
        if(where.length()>0){
            where.append(" AND ");
        }
        where.append(" 1=1 order by createTime desc");

        List<Person> persons = queryByWherePage(Person.class, where.toString(), CommonUtil.listToArray(parameters), offset, pageSize);
        List<PersonDto> personDtos = person.toPageDto(persons);
        return  personDtos;
    }

    @Override
    @Transactional
    public boolean personCreateOrUpdate(PersonDto dto,String [] roleIds) {
        Set<Role> sets = Sets.newHashSet();
        for (String ids : roleIds) {
            if(StringUtils.isNotBlank(ids)) {
                Role role1 = find(Role.class,ids);
                sets.add(role1);
            }
        }
        Person person = dto.toEntity(dto, sets);
        if(StringUtils.isNotBlank(dto.getId())){
            this.update(person);
        }else {
            person.setId(ManageUtils.getNumber());
            this.create(person);
        }
        return true;
    }

    /**
     *查询用户数量
     * @param dto
     * @return
     */
    public Long findPersonCount(PersonPageDto dto){
        List<Object> parameters = new ArrayList<>();

        StringBuffer where = new StringBuffer("") ;

        if (!StringUtils.isEmpty(dto.getName())){
            if(where.length()>0){
                where.append(" AND ");
            }
            where.append(" name like ? ");
            parameters.add("%"+dto.getName()+"%");
        }
        if (!StringUtils.isEmpty(dto.getDescription())){
            if(where.length()>0){
                where.append(" AND ");
            }
            where.append(" description like ? ");
            parameters.add("%"+dto.getDescription()+"%");
        }

        if(where.length()>0){
            where.append(" AND ");
        }
        where.append(" 1=1 order by createTime desc");
        return getCountByWhere(Person.class, where.toString(), CommonUtil.listToArray(parameters));
    }

    @Override
    public Long findRoleCount(RolePageDto dto) {
        List<Object> parameters = new ArrayList<>();

        StringBuffer where = new StringBuffer("") ;

        if (!StringUtils.isEmpty(dto.getName())){
            if(where.length()>0){
                where.append(" AND ");
            }
            where.append(" name like ? ");
            parameters.add("%"+dto.getName()+"%");
        }
        if (!StringUtils.isEmpty(dto.getDescription())){
            if(where.length()>0){
                where.append(" AND ");
            }
            where.append(" description like ? ");
            parameters.add("%"+dto.getDescription()+"%");
        }

        if(where.length()>0){
            where.append(" AND ");
        }
        where.append(" 1=1 order by createTime desc");
        return getCountByWhere(Role.class, where.toString(), CommonUtil.listToArray(parameters));
    }

    @Override
    public Long findPerminssionCount(PermissionPageDto dto) {
        List<Object> parameters = new ArrayList<>();

        StringBuffer where = new StringBuffer("") ;

        if (!StringUtils.isEmpty(dto.getName())){
            if(where.length()>0){
                where.append(" AND ");
            }
            where.append(" name like ? ");
            parameters.add("%"+dto.getName()+"%");
        }
        if (!StringUtils.isEmpty(dto.getDescription())){
            if(where.length()>0){
                where.append(" AND ");
            }
            where.append(" description like ? ");
            parameters.add("%"+dto.getDescription()+"%");
        }

        if(where.length()>0){
            where.append(" AND ");
        }
        where.append(" 1=1 order by createTime desc");
        return getCountByWhere(Permission.class, where.toString(), CommonUtil.listToArray(parameters));
    }

    @Override
    public List<PermissionDto> findPermissionDtoList() {
        List<Permission> all = (List<Permission>)this.findAll(Permission.class);
        List<PermissionDto> permissionDtos = permission.toPageDto(all);
        return permissionDtos;
    }

    @Override
    public List<RoleDto> findRoleDtoList() {
        List<Role> all = (List<Role>)this.findAll(Role.class);
        List<RoleDto> roleDtos = role.toPageDto(all);
        return roleDtos;
    }

    @Override
    public Object findAll(Class entityClass ) {
        String where = "1=1 order by createTime desc";
        List list = this.queryByWhereList(entityClass, where, null);
        return list;
    }

    @Override
    public Object findById(Class entityClass ,String id) {
        /*String where = "id="+id+" order by createTime desc";
        List list = this.queryByWhereList(entityClass, where, null);*/
        BaseEntity baseEntity = super.find(entityClass, id);
        return baseEntity;
    }

    @Override
    @Transactional
    public boolean deleteBy(Class clas , String id) {
        String sql = "delete from "+clas.getName()+" where id = ?";
        Object[] params = { id };
        this.updateByFullJPQL(sql, params);
        return true;
    }
}
